package com.feiyisys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feiyisys.dto.FindUPageDTO;
import com.feiyisys.dto.UpUserDTO;
import com.feiyisys.dto.UpdateUserStatusDTO;
import com.feiyisys.dto.UserLoginDTO;
import com.feiyisys.entity.Admin;
import com.feiyisys.entity.User;
import com.feiyisys.entity.Video;
import com.feiyisys.handlers.BaseContext;
import com.feiyisys.mapper.UserMapper;
import com.feiyisys.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feiyisys.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.security.SecureRandom;
import java.util.Date;

/**
 * <p>
 * 普通用户账号信息表 服务实现类
 * </p>
 *
 * @author wq
 * @since 2025-10-10
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;

    @Resource
    private JwtUtil jwtUtil;

    @Override
    public String login(UserLoginDTO userLoginDTO) {
        // 条件构造器，用来构建查询条件
        LambdaQueryWrapper<User> Wrapper = new LambdaQueryWrapper<>();
        // 设置查询条件，要求数据库里的username与前端传进来的username相等
        Wrapper.eq(User::getUsername, userLoginDTO.getUsername());
        // 调用getOne()方法，根据条件构造器查询数据库，返回User对象
        User user = this.getOne(Wrapper);
        if (user.getStatus() == 0){
            return "账号被禁用，请联管理员";
        }

        // 如果没有对应的user对象，则抛出异常
        // 抛出异常可以立即停止当前的执行流程
        if (user == null){
            throw new RuntimeException("用户名不存在或者密码不正确");
        }
        // 使用BCrypt算法的checkpw()方法对用户输入的密码和数据库里密码的哈希值进行匹配
        if(!BCrypt.checkpw(userLoginDTO.getPassword(), user.getPassword())){
            throw new RuntimeException("用户名不存在或者密码不正确");
        }

        // Claims是一个Map集合（双列集合 Key,Value）
        // JWT（JSON Web Token)
        // Jwts.claims()：创建一个新的 Claims 对象，该对象可以用来设置JWT中的声明信息。
        Claims claims = Jwts.claims();
        // 将user的id存放在claims中
        claims.put("id",user.getId());
        String token=jwtUtil.createToken(claims);
        //获取当前时间
        Date now = new Date();
        user.setLastLoginTime(now);
        this.updateById(user);

        return token;
    }

    @Override
    public void saveUser(User user) {
        // 验证用户名和密码格式
        if (user.getUsername() == null || user.getUsername().length() < 3) {
            throw new RuntimeException("用户名至少需要3位");
        }
        if (user.getPassword() == null || user.getPassword().length() < 8) {
            throw new RuntimeException("密码至少需要8位");
        }

        // 密码加密处理
        String encryptedPwd = BCrypt.hashpw(user.getPassword(), BCrypt.gensalt());
        log.info("原始密码：{} | 加密后的密文：{}", user.getPassword(), encryptedPwd);

        //保存加密后的密码
        user.setPassword(encryptedPwd);
        this.save(user);
    }

    @Override
    public void updateInfo(UpUserDTO upUserDTO) {
        User user = new User();
        BeanUtil.copyProperties(upUserDTO, user);
        this.updateById(user);
    }

    @Override
    public IPage<User> findPage(FindUPageDTO findUPageDTO) {
        // 创建分页对象
        Page<User> page = new Page<>(findUPageDTO.getCurrent(), findUPageDTO.getSize());

        // 创建查询条件
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(findUPageDTO.getUsername() != null, User::getUsername, findUPageDTO.getUsername());
        // 执行分页查询
        return this.page(page, wrapper);
    }

    @Override
    public Object updateIsUse(UpdateUserStatusDTO updateUserStatusDTO) {

        Long id = updateUserStatusDTO.getId();
        log.info("id:{}",id);
        Byte status = updateUserStatusDTO.getStatus();

        User user = this.getById(id);
        if (user == null) {
            throw new RuntimeException("视频不存在");
        }

        user.setStatus(status);
        return this.updateById(user);
    }

    @Override
    public String findPwd(String email) {
        if (email != null) {
            email = email.replace("\"", "");
        }
        log.info("查询邮箱: [{}]", email);
        User one = this.getOne(new LambdaQueryWrapper<User>().eq(User::getEmail, email));
        if (one == null) {
            throw new RuntimeException("用户不存在");
        }
        //重置密码生成8位随机数
        String newPwd = String.format("%08d", (int)(Math.random() * 100000000));
        log.info("新密码：{}", newPwd);
        String b = newPwd;
        newPwd = BCrypt.hashpw(newPwd, BCrypt.gensalt());
        log.info("加密后的新密码：{}", newPwd);
        one.setPassword(newPwd);
        this.updateById(one);
        return b;
    }


}
